

// Copyright (c) WanSheng Intelligent Corp. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#ifndef __duration_dist_h__
#define __duration_dist_h__
#include "stdbool.h"
#include<stdio.h>

typedef int (*bh_duration_alarm_handler) (void * stats);

#ifdef __cplusplus

class CDistCounter
{
public:
    CDistCounter(const char * name, unsigned int period, 
        unsigned int quick_count_base = 0,
        unsigned int quick_count_size = 100);
    ~CDistCounter();
    time_t m_stats_start;
    std::string m_name;

    // length of stats unit
    unsigned int m_period;    

    bool m_alarmed;

    // the times over the alarm_level to trigger the alarm
    unsigned int m_alarm_threshold;
    unsigned int m_over_cnt;
    unsigned int m_total;

    bh_duration_alarm_handler m_alarm_hander;

    void counting(unsigned int);
    void reset();
    char * get_report(FILE* stream  = NULL);
    bool check(int *, unsigned int internval);

    unsigned int * m_quick_counts;
    unsigned int  m_quick_count_base;
    unsigned int m_quick_count_size;

    unsigned int m_missing_counts;

   
private:
    bool lock(bool block_wait = true);
    void unlock();
    
    pthread_mutex_t m_condition_mutex;
    std::map<unsigned int, unsigned int> m_durations;
    void* m_atomic_lock;

};

extern "C" {
#endif  //__cplusplus



typedef  void* duration_manager_t ;
typedef void*  duration_counter_t ;
#define DEFAULT_DURATION_MGR (duration_manager_t) NULL

duration_manager_t ws_get_default_count_mgr();
duration_manager_t ws_create_duration_manager();
void ws_destory_duration_manager(duration_manager_t manager);

// start a thread to report the duration distribution stats periodically
// manager: It can NULL which means the default manager.
// report_seconds: the seconds for a reporting period
// report_path: the path for the report file, "/tmp/duration_stats.txt" by default. It can be NULL.
void ws_start_duration_report(duration_manager_t manager, unsigned int report_seconds, const char * report_path);


// manager: can be NULL, the default manager will be used.
// counter_name: used for reporting. Must be unique under a manager
duration_counter_t ws_create_duration_counter(duration_manager_t manager, const char * counter_name, unsigned int period);

// quick count is for reducing performance overhead. all the keys located in the quick count base with size range
// will be counted in array rather than map
duration_counter_t ws_create_duration_counter2(duration_manager_t manager, const char * counter_name, unsigned int period, 
    unsigned int quick_count_base ,
    unsigned int quick_count_size);


void ws_count_duration(duration_counter_t counter, unsigned int duration);

bool ws_count_duration2(duration_manager_t manager,
        const char * counter_name,
        unsigned int duration);

char * ws_counter_report(duration_counter_t counter);

void count_alarm_settings(duration_counter_t counter, 
        unsigned int alarm_threshold,  
        bh_duration_alarm_handler alarm_handler);

#ifdef __cplusplus
}
#endif
#endif